<script setup>
import { toRefs, createApp, reactive } from 'vue';
import EditInput from './EditInput';

let editInputApp = null;

//定义响应式数据
const state = reactive({
  key: '',
  value: '',
  index: -1,
  text: ''
});

//定义属性
const props = defineProps({
  data: {
    type: Object,
    default: () => ({
      tHead: [],
      tBody: []
    })
  }
});

const emit = defineEmits(['submit']);
const { tHead, tBody } = toRefs(props.data);

//显示编辑输入框
const showEditInput = (event, key, index) => {
  // console.log(event, key, index);
  //PointerEvent {...} 'english' 2

  //如果组件实例存在时移除它
  editInputApp && removeEditInputApp(editInputApp);

  //如果是不可编辑的,中止向下执行程序
  if (!checkEditable(key)) return;

  const target = event.target;
  // console.log(target);
  //<td data-v-12dac2ea="">lisi</td>

  // console.log(target.textContent);
  //lisi

  const oFrag = document.createDocumentFragment();

  //创建组件实例并传入参数
  editInputApp = createApp(EditInput, {
    value: target.textContent,
    setValue: setValue
  });

  //挂载
  if (editInputApp) {
    editInputApp.mount(oFrag);
    target.appendChild(oFrag);

    //选中td
    target.querySelector('.edit-input').select();
  }

  //设置属性
  setData({ index, key, text: findText(key) });
};

//事件绑定
window.addEventListener('click', removeEditInputApp, false);

function setData({ index, key, text, value = '' }) {
  state.key = key;
  state.index = index;
  state.value = value;
  state.text = text;
}

function findText(key) {
  const { text } = tHead.value.find((item) => item.key === key);
  return text;
}

//修改值
function setValue(value) {
  state.value = value;
  emit('submit', { ...state }, removeEditInputApp);
}

//移除组件实例
function removeEditInputApp() {
  //unmount卸载应用实例的根组件
  editInputApp && editInputApp.unmount();

  //还原
  setData({
    index: -1,
    key: '',
    value: '',
    text: ''
  });
}

//检测是否可以编辑
function checkEditable(key) {
  const { editable } = tHead.value.find((item) => item.key === key);
  return editable;
}
</script>

<template>
  <table border="1" class="my-table">
    <thead>
      <tr>
        <th v-for="info of tHead" :key="info.key">{{ info.text }}</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="(item, index) of tBody" :key="item.id">
        <td
          v-for="(value, key) in item"
          :key="key"
          @click.stop="showEditInput($event, key, index)"
        >
          {{ value }}
        </td>
      </tr>
    </tbody>
  </table>
</template>

<style lang="scss" scoped>
.my-table {
  width: 100%;
  border-collapse: collapse;

  tr {
    height: 44px;

    td {
      position: relative;
      text-align: center;
      cursor: pointer;
    }
  }
}
</style>
